﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Infrastructure;
using Picking_Winform.Util;

namespace Picking_Winform
{
    public partial class CheckSpecifiedPointView : FormBase
    {
        public CheckPointFormType FormType { get; set; }
        private InterfaceUpdateHandler LightInfoHandle;
        private int turnOffLightNumInOneCommand = 1;
        private string turnOffLightSuffixInfoInCommand = string.Empty;
        private string turnOffLightCommandHeader = "D";

        /// <summary>
        /// Constructor
        /// </summary>
        public CheckSpecifiedPointView()
        {
            InitializeComponent();
            this.Shown += new EventHandler(CheckSpecifiedPointView_Shown);
            this.Controls.Add(base.txtTitle);
        }

        /// <summary>
        /// Get Form Width
        /// </summary>
        /// <returns></returns>
        protected override int GetFormWidth()
        {
            return Screen.PrimaryScreen.WorkingArea.Width;
        }

        /// <summary>
        /// Load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckSpecifiedPointView_Load(object sender, EventArgs e)
        {
            this.LightInfoHandle
                = new InterfaceUpdateHandler(HandleUpdateLightInfo);

            this.InitAIPlug();

#if DEBUG
            this.cmbSerialPortTest.Visible = true;
            this.btnTest.Visible = true;
            this.btnLoad.Visible = true;
#endif
        }

        /// <summary>
        /// Shown
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CheckSpecifiedPointView_Shown(object sender, EventArgs e)
        {
            this.SetFormTitle();
            this.TurnOnLEDYellow();
        }

        /// <summary>
        /// Set Form Title
        /// </summary>
        private void SetFormTitle()
        {
            switch (FormType)
            {
                case CheckPointFormType.CheckAllPoints:
                    this.Text = txtTitle.Text = "点检";
                    this.tlpLightRange.Visible = false;
                    ////panelSetupLightsRange.Visible = false;
                    ////liLightsInfo.Location = new Point(12, 89);
                    ////liLightsInfo.Height = 400;
                    break;
                case CheckPointFormType.CheckSpecifiedPoints:
                    this.Text = txtTitle.Text = "指定地址位灯检查";
                    this.tlpLightRange.Visible = true;
                    ////panelSetupLightsRange.Visible = true;
                    ////liLightsInfo.Location = new Point(12, 220);
                    ////liLightsInfo.Height = 270;
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Size Changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckSpecifiedPointView_SizeChanged(object sender, EventArgs e)
        {
            this.tlpMain.Height = this.Height - 120;
        }

        /// <summary>
        /// Init AIPlug
        /// </summary>
        private void InitAIPlug()
        {
            if (!string.IsNullOrWhiteSpace(ConfigInfo.AxAiPlugIpAddress))
            {
                axAiPlug.ConnectSocket(ConfigInfo.AxAiPlugIpAddress, ConfigInfo.AxAiPlugPort);

                axAiPlug.StartPolling(); //watch the data arrival

                axAiPlug.BinaryMode = true; //set to true

                axAiPlug.CommandTimeout = 5000; //set to 5000

                this.axAiPlug.DataArrival
                    += new AxAiPlugControl.@__AiPlug_DataArrivalEventHandler(this.axAiPlug_DataArrival);
            }
        }

        /// <summary>
        /// Display Light No
        /// </summary>
        /// <param name="startLightNo"></param>
        /// <param name="endLightNo"></param>
        private void DisplayLightNo(int startLightNo, int endLightNo)
        {
            if (this.FormType == CheckPointFormType.CheckAllPoints)
            {
                this.liLightsInfo.Items.Clear();
            }

            for (int lightNo = startLightNo; lightNo <= endLightNo; lightNo++)
            {
                string item = lightNo.ToString("0000");

                if (!this.liLightsInfo.Items.ContainsKey(item))
                {
                    this.liLightsInfo.Items.Add(item, item, 0);
                }
                else
                {
                    this.liLightsInfo.Items[item].ForeColor = System.Drawing.Color.RoyalBlue;
                }
            }
        }

        /// <summary>
        /// Turn On Light
        /// </summary>
        /// <param name="startLightNo"></param>
        /// <param name="endLightNo"></param>
        private void TurnOnLight(int startLightNo, int endLightNo)
        {
            List<string> lightNos = new List<string>();

            for (int lightNo = startLightNo; lightNo <= endLightNo; lightNo++)
            {
                lightNos.Add(lightNo.ToString("0000"));
            }

            this.TurnOnLight(lightNos);
        }

        /// <summary>
        /// Turn On Light
        /// </summary>
        /// <param name="lightNos"></param>
        private void TurnOnLight(List<string> lightNos)
        {
            string lightNoToTurnOn = string.Empty;

            foreach (string item in lightNos)
            {
                lightNoToTurnOn += item + "88888";

                if (lightNoToTurnOn.Trim().Length >= (ConfigInfo.LightNumInOneCommand * 9))
                {
                    this.axAiPlug.SendCommand("P100" + lightNoToTurnOn.Trim());
                    lightNoToTurnOn = string.Empty;
                }
            }

            if (!string.IsNullOrEmpty(lightNoToTurnOn.Trim()))
            {
                this.axAiPlug.SendCommand("P100" + lightNoToTurnOn.Trim());
            }
        }

        /// <summary>
        /// Turn Off Light
        /// </summary>
        /// <param name="startLightNo"></param>
        /// <param name="endLightNo"></param>
        private void TurnOffLight(int startLightNo, int endLightNo)
        {
            List<string> lightNos = new List<string>();

            for (int lightNo = startLightNo; lightNo <= endLightNo; lightNo++)
            {
                lightNos.Add(lightNo.ToString("0000"));
            }

            this.TurnOffLight(lightNos);
        }

        /// <summary>
        /// Turn Off Light
        /// </summary>
        /// <param name="lightNos"></param>
        private void TurnOffLight(List<string> lightNos)
        {
            string lightNoToTurnOff = string.Empty;

            foreach (string item in lightNos)
            {
                int lengthTemp = item.Length + this.turnOffLightSuffixInfoInCommand.Length;
                lightNoToTurnOff += item + this.turnOffLightSuffixInfoInCommand;

                if (lightNoToTurnOff.Trim().Length >= (this.turnOffLightNumInOneCommand * lengthTemp))
                {
                    this.axAiPlug.SendCommand(this.turnOffLightCommandHeader + lightNoToTurnOff.Trim());
                    lightNoToTurnOff = string.Empty;
                }
            }

            if (!string.IsNullOrEmpty(lightNoToTurnOff.Trim()))
            {
                this.axAiPlug.SendCommand(this.turnOffLightCommandHeader + lightNoToTurnOff.Trim());
            }
        }

        /// <summary>
        /// Turn On LED Yellow
        /// </summary>
        private void TurnOnLEDYellow()
        {
            //this.axAiPlug.SendCommand("T" + ConfigInfo.CmdLEDYellow.Trim());
        }

        /// <summary>
        /// Turn On LED Red
        /// </summary>
        private void TurnOnLEDRed()
        {
            this.axAiPlug.SendCommand("T" + ConfigInfo.CmdLEDRed.Trim());
        }

        /// <summary>
        /// Turn On LED Beep
        /// </summary>
        private void TurnOnLEDBeep()
        {
            //this.axAiPlug.SendCommand("T" + ConfigInfo.CmdLEDBeep.Trim());
        }

        /// <summary>
        /// Turn On LED Red And Beep
        /// </summary>
        private void TurnOnLEDRedAndBeep()
        {
            this.TurnOnLEDRed();
            //this.TurnOnLEDBeep();
        }

        /// <summary>
        /// Is All Light Turned Off
        /// </summary>
        /// <param name="ltvLight"></param>
        /// <returns></returns>
        private bool IsAllLightTurnedOff(ListView ltvLight)
        {
            bool isAllLightTurnedOff = true;

            for (int i = ltvLight.Items.Count - 1; i >= 0; i--)
            {
                if (ltvLight.Items[i].ForeColor != System.Drawing.Color.Gray)
                {
                    isAllLightTurnedOff = false;
                    break;
                }
            }

            return isAllLightTurnedOff;
        }

        /// <summary>
        /// Handle Update Light Info
        /// </summary>
        /// <param name="data"></param>
        /// <param name="port"></param>
        private void HandleUpdateLightInfo(string data, string port)
        {
            string lightNo = this.GetLightNo(data);
            string lightStatus = this.GetLightStatus(data);

            this.UpdateLightInfo(this.liLightsInfo, lightNo, lightStatus);
        }

        /// <summary>
        /// Get Light No
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private string GetLightNo(string data)
        {
            string lightNo = string.Empty;
            lightNo = data.Substring(1, 4);

            return lightNo;
        }

        /// <summary>
        /// Get Light Status
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private string GetLightStatus(string data)
        {
            string status = string.Empty;
            if (data.Length >= 7)
            {
                status = data.Substring(5, 2);
            }
            else if (data.Length >= 6)
            {
                status = data.Substring(5, data.Length - 5);
            }

            return status;
        }

        /// <summary>
        /// Update Light Info
        /// </summary>
        /// <param name="ltvLight"></param>
        /// <param name="lightNo"></param>
        /// <param name="lightStatus"></param>
        private void UpdateLightInfo(ListView ltvLight, string lightNo, string lightStatus)
        {
            for (int i = ltvLight.Items.Count - 1; i >= 0; i--)
            {
                if (string.Equals(ltvLight.Items[i].Text.Substring(0, lightNo.Length), lightNo))
                {
                    if (string.Equals(lightStatus, "00"))
                    {
                        ////ltvLight.Items[i].Remove();
                        ltvLight.Items[i].ForeColor = System.Drawing.Color.Gray;
                    }
                    else
                    {
                        ////ltvLight.Items[i].Text = lightNo + "异常";
                        ltvLight.Items[i].ForeColor = System.Drawing.Color.Red;
                        this.TurnOnLEDRedAndBeep();
                    }
                }
            }

            if (this.IsAllLightTurnedOff(ltvLight))
            {
                ltvLight.Items.Clear();
            }
        }

        /// <summary>
        /// Clear Light No
        /// </summary>
        /// <param name="startLightNo"></param>
        /// <param name="endLightNo"></param>
        private void ClearLightNo(int startLightNo, int endLightNo)
        {
            for (int lightNo = startLightNo; lightNo <= endLightNo; lightNo++)
            {
                string item = lightNo.ToString("0000");
                this.UpdateLightInfo(this.liLightsInfo, item, "00");
            }
        }

        /// <summary>
        /// Do Validation
        /// </summary>
        /// <returns></returns>
        private bool DoValidation()
        {
            int startLightNumber = 0;
            int endLightNumber = 0;

            string lightStartNo = this.txtLightsFrom.Text.Trim();
            string lightEndNo = this.txtLightsTo.Text.Trim();

            if (string.IsNullOrEmpty(lightStartNo))
            {
                MessageBox.Show("开始棚灯号不能为空!",
                                "验证",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);
                return false;
            }
            else
            {
                if (!int.TryParse(lightStartNo, out startLightNumber))
                {
                    MessageBox.Show("开始棚灯号必须是个整型数值!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }

                if (startLightNumber > ConfigInfo.MaxLightAddress)
                {
                    MessageBox.Show("开始棚灯号必须小于或等于最大棚灯号：" + ConfigInfo.MaxLightAddress.ToString() + "!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }

                if (startLightNumber < ConfigInfo.MinLightAddress)
                {
                    MessageBox.Show("开始棚灯号必须大于或等于最小棚灯号：" + ConfigInfo.MinLightAddress.ToString() + "!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }
            }

            if (string.IsNullOrEmpty(lightEndNo))
            {
                MessageBox.Show("结束棚灯号不能为空!",
                                "验证",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);
                return false;
            }
            else
            {
                if (!int.TryParse(lightEndNo, out endLightNumber))
                {
                    MessageBox.Show("结束棚灯号必须是个整型数值!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }

                if (endLightNumber > ConfigInfo.MaxLightAddress)
                {
                    MessageBox.Show("结束棚灯号必须小于或等于最大棚灯号：" + ConfigInfo.MaxLightAddress.ToString() + "!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }

                if (endLightNumber < ConfigInfo.MinLightAddress)
                {
                    MessageBox.Show("结束棚灯号必须大于或等于最小棚灯号：" + ConfigInfo.MinLightAddress.ToString() + "!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }
            }

            if (!string.IsNullOrEmpty(lightStartNo)
                && !string.IsNullOrEmpty(lightEndNo))
            {
                if (startLightNumber > endLightNumber)
                {
                    MessageBox.Show("结束棚灯号必须大于或等于开始棚灯号!",
                                    "验证",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Warning);

                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Turn On Lights
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTurnOnLights_Click(object sender, EventArgs e)
        {
            switch (FormType)
            {
                case CheckPointFormType.CheckAllPoints:

                    this.DisplayLightNo(ConfigInfo.MinLightAddress, ConfigInfo.MaxLightAddress);
                    this.TurnOnLight(ConfigInfo.MinLightAddress, ConfigInfo.MaxLightAddress);
                    ////axAiPlug.SendCommand("A");

                    break;

                case CheckPointFormType.CheckSpecifiedPoints:

                    if (!this.DoValidation())
                    {
                        return;
                    }

                    int startLightNo = 0;
                    int endLightNo = 0;

                    int.TryParse(this.txtLightsFrom.Text.Trim(), out startLightNo);
                    int.TryParse(this.txtLightsTo.Text.Trim(), out endLightNo);

                    this.DisplayLightNo(startLightNo, endLightNo);
                    this.TurnOnLight(startLightNo, endLightNo);

                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// Turn Off Lights
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTurnOffLights_Click(object sender, EventArgs e)
        {
            ////axAiPlug.SendCommand("Z");

            if (this.FormType == CheckPointFormType.CheckAllPoints)
            {
                this.TurnOffLight(ConfigInfo.MinLightAddress, ConfigInfo.MaxLightAddress);
                this.liLightsInfo.Items.Clear();
            }
            else
            {
                int startLightNo = 0;
                int endLightNo = 0;

                int.TryParse(this.txtLightsFrom.Text.Trim(), out startLightNo);
                int.TryParse(this.txtLightsTo.Text.Trim(), out endLightNo);

                this.TurnOffLight(startLightNo, endLightNo);
                this.ClearLightNo(startLightNo, endLightNo);

                ////List<string> lightNos = new List<string>();

                ////for (int i = 0; i < this.liLightsInfo.Items.Count; i++)
                ////{
                ////    if (this.liLightsInfo.Items[i].ForeColor != System.Drawing.Color.Gray)
                ////    {
                ////        int textLenght = this.liLightsInfo.Items[i].Text.Length;

                ////        if (textLenght >= 4)
                ////        {
                ////            lightNos.Add(this.liLightsInfo.Items[i].Text.Substring(0, 4));
                ////        }
                ////        else
                ////        {
                ////            lightNos.Add(this.liLightsInfo.Items[i].Text.Substring(0, textLenght));
                ////        }
                ////    }
                ////}

                ////this.TurnOnLight(lightNos);
            }
        }

        /// <summary>
        /// Return
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReturn_Click(object sender, EventArgs e)
        {
            this.TurnOffLight(ConfigInfo.MinLightAddress, ConfigInfo.MaxLightAddress);
            CloseCurrentWindow();
        }

        /// <summary>
        /// Form Closing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CheckSpecifiedPointView_FormClosing(object sender, FormClosingEventArgs e)
        {
            axAiPlug.SendCommand("T80010");
            axAiPlug.StopPolling();
            axAiPlug.Dispose();
        }

        /// <summary>
        /// Data Arrival
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void axAiPlug_DataArrival(object sender, AxAiPlugControl.__AiPlug_DataArrivalEvent e)
        {
            string data = e.data;
            //data=t000100xxxx
            //t:fixed, 0001:light no, 
            //00:normal(else:exception)

            data = data.Replace("\n", string.Empty);
            data = data.Replace("\r", string.Empty);

            if (data.Length < 5)
            {
                return;
            }

            if (LightInfoHandle != null)
            {
                this.Invoke(LightInfoHandle,
                            new string[] { data, string.Empty });
            }
        }

        /// <summary>
        /// Load Data For Test
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLoad_Click(object sender, EventArgs e)
        {
            this.cmbSerialPortTest.Items.Clear();
            for (int i = 0; i < this.liLightsInfo.Items.Count; i++)
            {
                this.cmbSerialPortTest.Items.Add("t" + this.liLightsInfo.Items[i].Text + "01");
            }
        }

        /// <summary>
        /// Test
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTest_Click(object sender, EventArgs e)
        {
            AxAiPlugControl.__AiPlug_DataArrivalEvent e2
                = new AxAiPlugControl.__AiPlug_DataArrivalEvent(this.cmbSerialPortTest.Text);

            this.axAiPlug_DataArrival(null, e2);
        }
    }
}
